package zpp_nape.shape;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class ZPP_Polygon extends ZPP_Shape{
    public var outer_zn:Polygon;
    public var lverts:ZPP_Vec2;
    public var wrap_lverts:Vec2List;
    public var gverts:ZPP_Vec2;
    public var wrap_gverts:Vec2List;
    public var edges:ZNPList_ZPP_Edge;
    public var wrap_edges:EdgeList;
    public var edgeCnt:Int;
    public var reverse_flag:Bool;
    #if swc@:keep#end public function get_lverts(){
        var me=this;
        wrap_lverts=ZPP_MixVec2List.get(lverts);
        wrap_lverts.zpp_inner.post_adder=function(x:Vec2){
            x.zpp_inner._invalidate=function(x:ZPP_Vec2){
                me.invalidate_lverts();
            };
            x.zpp_inner._immutable=function(){
                if(me.body!=null&&me.body.isStatic()&&me.body.space!=null)throw "Error: Cannot modify local vertex of Polygon added to a static body whilst within a Space";
            };
            var ite:ZPP_Vec2=null;
            var ite2:ZNPNode_ZPP_Edge=null;
            {
                var cx_ite=me.lverts.begin();
                while(cx_ite!=null){
                    var i=cx_ite.elem();
                    {
                        if(i==x.zpp_inner)break;
                        else{
                            ite=ite==null?me.gverts.begin():ite.next;
                            ite2=ite2==null?me.edges.begin():ite2.next;
                        }
                    };
                    cx_ite=cx_ite.next;
                }
            };
            var vec=ZPP_Vec2.get(0,0,true);
            me.gverts.insert(ite,vec);
            if(me.lverts.begin().next!=null){
                if(me.lverts.begin().next.next==null){
                    var ed:ZPP_Edge={
                        if(ZPP_Edge.zpp_pool==null)new ZPP_Edge();
                        else{
                            var ret=ZPP_Edge.zpp_pool;
                            ZPP_Edge.zpp_pool=ret.next;
                            ret;
                        }
                    };
                    ed.polygon=me;
                    me.edges.add(ed);
                    var ed:ZPP_Edge={
                        if(ZPP_Edge.zpp_pool==null)new ZPP_Edge();
                        else{
                            var ret=ZPP_Edge.zpp_pool;
                            ZPP_Edge.zpp_pool=ret.next;
                            ret;
                        }
                    };
                    ed.polygon=me;
                    me.edges.add(ed);
                    me.edgeCnt+=2;
                }
                else{
                    var ed:ZPP_Edge={
                        if(ZPP_Edge.zpp_pool==null)new ZPP_Edge();
                        else{
                            var ret=ZPP_Edge.zpp_pool;
                            ZPP_Edge.zpp_pool=ret.next;
                            ret;
                        }
                    };
                    ed.polygon=me;
                    me.edges.insert(ite2,ed);
                    me.edgeCnt++;
                }
            }
            vec._validate=function(){
                if(me.body==null)throw "Error: World vertex only makes sense when Polygon is contained in a rigid body";
                me.validate_gverts();
            };
        }
        wrap_lverts.zpp_inner.subber=function(x:Vec2){
            var ite:ZPP_Vec2=null;
            var ite2:ZNPNode_ZPP_Edge=null;
            {
                var cx_ite=me.lverts.begin();
                while(cx_ite!=null){
                    var i=cx_ite.elem();
                    {
                        if(i==x.zpp_inner)break;
                        else{
                            ite=ite==null?me.gverts.begin():ite.next;
                            ite2=ite2==null?me.edges.begin():ite2.next;
                        }
                    };
                    cx_ite=cx_ite.next;
                }
            };
            var rem=(ite==null?me.gverts.front():ite.next.elem());
            me.gverts.erase(ite);
            {
                var o=rem;
                {
                    #if NAPE_ASSERT var res={
                        o!=null;
                    };
                    if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_Vec2"+", in obj: "+"rem"+")");
                    #end
                };
                o.free();
                o.next=ZPP_Vec2.zpp_pool;
                ZPP_Vec2.zpp_pool=o;
            };
            if(me.lverts.begin()!=null){
                if(me.lverts.begin().next==null){
                    {
                        var o=me.edges.front();
                        {
                            #if NAPE_ASSERT var res={
                                o!=null;
                            };
                            if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_Edge"+", in obj: "+"me.edges.front()"+")");
                            #end
                        };
                        o.free();
                        o.next=ZPP_Edge.zpp_pool;
                        ZPP_Edge.zpp_pool=o;
                    };
                    me.edges.pop();
                    {
                        var o=me.edges.front();
                        {
                            #if NAPE_ASSERT var res={
                                o!=null;
                            };
                            if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_Edge"+", in obj: "+"me.edges.front()"+")");
                            #end
                        };
                        o.free();
                        o.next=ZPP_Edge.zpp_pool;
                        ZPP_Edge.zpp_pool=o;
                    };
                    me.edges.pop();
                    me.edgeCnt-=2;
                }
                else{
                    var rem=(ite2==null?me.edges.front():ite2.next.elem());
                    me.edges.erase(ite2);
                    {
                        var o=rem;
                        {
                            #if NAPE_ASSERT var res={
                                o!=null;
                            };
                            if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_Edge"+", in obj: "+"rem"+")");
                            #end
                        };
                        o.free();
                        o.next=ZPP_Edge.zpp_pool;
                        ZPP_Edge.zpp_pool=o;
                    };
                    me.edgeCnt--;
                }
            }
        };
        wrap_lverts.zpp_inner._invalidate=function(_){
            me.invalidate_lverts();
        };
        wrap_lverts.zpp_inner._validate=function(){
            me.validate_lverts();
        };
        wrap_lverts.zpp_inner._modifiable=function(){
            if(me.body!=null&&me.body.isStatic()&&me.body.space!=null)throw "Error: Cannot modifiy shapes of static object once added to Space";
        };
        wrap_lverts.zpp_inner.reverse_flag=reverse_flag;
    }
    public function get_gverts(){
        var me=this;
        wrap_gverts=ZPP_MixVec2List.get(gverts,true);
        wrap_gverts.zpp_inner.reverse_flag=reverse_flag;
        wrap_gverts.zpp_inner._validate=function(){
            me.validate_gverts();
        };
    }
    public function get_edges(){
        var me=this;
        wrap_edges=ZPP_EdgeList.get(edges,true);
        wrap_edges.zpp_inner.reverse_flag=reverse_flag;
        wrap_edges.zpp_inner._validate=function(){
            me.validate_lverts();
        };
    }
    public var zip_lverts:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate_lverts(){
        invalidate_laxi();
        invalidate_area_inertia();
        invalidate_angDrag();
        invalidate_localCOM();
        invalidate_gverts();
        zip_lverts=true;
        zip_valid=true;
        if(body!=null)body.wakeall();
    }
    public var zip_laxi:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate_laxi(){
        invalidate_gaxi();
        zip_laxi=true;
    }
    public var zip_gverts:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate_gverts(){
        invalidate_aabb();
        zip_gverts=true;
    }
    public var zip_gaxi:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate_gaxi(){
        zip_gaxi=true;
    }
    public var zip_valid:Bool;
    public var validation:ValidationResult;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function valid(){
        if(zip_valid){
            zip_valid=false;
            validate_lverts();
            if(lverts.size()<3)return validation=ValidationResult.DEGENERATE;
            else{
                validate_area_inertia();
                if(area<ZPP_Const.EPSILON)return validation=ValidationResult.DEGENERATE;
                else{
                    var cont=true;
                    {
                        var cx_cont=true;
                        var cx_ite=lverts.begin();
                        var u=cx_ite.elem();
                        cx_ite=cx_ite.next;
                        while(cx_ite!=null){
                            var v=cx_ite.elem();
                            {
                                var dx:Float;
                                var dy:Float;
                                {
                                    dx=v.x-u.x;
                                    dy=v.y-u.y;
                                };
                                if((dx*dx+dy*dy)<ZPP_Const.EPSILON){
                                    cont=false;
                                    {
                                        cx_cont=false;
                                        break;
                                    };
                                }
                            };
                            {
                                u=v;
                                cx_ite=cx_ite.next;
                            };
                        }
                        if(cx_cont){
                            do{
                                var v=lverts.front();
                                {
                                    var dx:Float;
                                    var dy:Float;
                                    {
                                        dx=v.x-u.x;
                                        dy=v.y-u.y;
                                    };
                                    if((dx*dx+dy*dy)<ZPP_Const.EPSILON){
                                        cont=false;
                                        break;
                                    }
                                };
                            }
                            while(false);
                        }
                    };
                    if(!cont)return validation=ValidationResult.DEGENERATE_EDGES;
                    else{
                        var neg=false;
                        var pos=false;
                        {
                            var cx_cont=true;
                            var cx_ite=lverts.begin();
                            var u=cx_ite.elem();
                            cx_ite=cx_ite.next;
                            var v=cx_ite.elem();
                            cx_ite=cx_ite.next;
                            while(cx_ite!=null){
                                var w=cx_ite.elem();
                                {
                                    var ax:Float;
                                    var ay:Float;
                                    {
                                        ax=w.x-v.x;
                                        ay=w.y-v.y;
                                    };
                                    var bx:Float;
                                    var by:Float;
                                    {
                                        bx=v.x-u.x;
                                        by=v.y-u.y;
                                    };
                                    var dot=(by*ax-bx*ay);
                                    if(dot>ZPP_Const.EPSILON)pos=true;
                                    else if(dot<-ZPP_Const.EPSILON)neg=true;
                                    if(pos&&neg){
                                        cx_cont=false;
                                        break;
                                    };
                                };
                                {
                                    u=v;
                                    v=w;
                                    cx_ite=cx_ite.next;
                                };
                            }
                            if(cx_cont){
                                cx_ite=lverts.begin();
                                var w=cx_ite.elem();
                                do{
                                    {
                                        var ax:Float;
                                        var ay:Float;
                                        {
                                            ax=w.x-v.x;
                                            ay=w.y-v.y;
                                        };
                                        var bx:Float;
                                        var by:Float;
                                        {
                                            bx=v.x-u.x;
                                            by=v.y-u.y;
                                        };
                                        var dot=(by*ax-bx*ay);
                                        if(dot>ZPP_Const.EPSILON)pos=true;
                                        else if(dot<-ZPP_Const.EPSILON)neg=true;
                                        if(pos&&neg){
                                            cx_cont=false;
                                            break;
                                        };
                                    };
                                }
                                while(false);
                                if(cx_cont){
                                    {
                                        u=v;
                                        v=w;
                                        cx_ite=cx_ite.next;
                                    };
                                    var w=cx_ite.elem();
                                    do{
                                        {
                                            var ax:Float;
                                            var ay:Float;
                                            {
                                                ax=w.x-v.x;
                                                ay=w.y-v.y;
                                            };
                                            var bx:Float;
                                            var by:Float;
                                            {
                                                bx=v.x-u.x;
                                                by=v.y-u.y;
                                            };
                                            var dot=(by*ax-bx*ay);
                                            if(dot>ZPP_Const.EPSILON)pos=true;
                                            else if(dot<-ZPP_Const.EPSILON)neg=true;
                                            if(pos&&neg)break;
                                        };
                                    }
                                    while(false);
                                }
                            }
                        };
                        if(pos&&neg)return validation=ValidationResult.CONCAVE;
                        else{
                            cont=true;
                            {
                                var cx_cont=true;
                                var cx_ite=lverts.begin();
                                var u=cx_ite.elem();
                                cx_ite=cx_ite.next;
                                while(cx_ite!=null){
                                    var v=cx_ite.elem();
                                    {
                                        if(!cont){
                                            cx_cont=false;
                                            break;
                                        };
                                        {
                                            var cx_cont=true;
                                            var cx_ite=lverts.begin();
                                            var a=cx_ite.elem();
                                            cx_ite=cx_ite.next;
                                            while(cx_ite!=null){
                                                var b=cx_ite.elem();
                                                {
                                                    if(u==a||u==b||v==a||v==b){
                                                        {
                                                            a=b;
                                                            cx_ite=cx_ite.next;
                                                        };
                                                        continue;
                                                    };
                                                    var sx:Float;
                                                    var sy:Float;
                                                    {
                                                        sx=u.x-a.x;
                                                        sy=u.y-a.y;
                                                    };
                                                    var vx:Float;
                                                    var vy:Float;
                                                    {
                                                        vx=v.x-u.x;
                                                        vy=v.y-u.y;
                                                    };
                                                    var qx:Float;
                                                    var qy:Float;
                                                    {
                                                        qx=b.x-a.x;
                                                        qy=b.y-a.y;
                                                    };
                                                    var den=(vy*qx-vx*qy);
                                                    if(den*den>ZPP_Const.EPSILON){
                                                        den=1/den;
                                                        var t=(qy*sx-qx*sy)*den;
                                                        if(t>ZPP_Const.EPSILON&&t<1-ZPP_Const.EPSILON){
                                                            var s=(vy*sx-vx*sy)*den;
                                                            if(s>ZPP_Const.EPSILON&&s<1-ZPP_Const.EPSILON){
                                                                cont=false;
                                                                {
                                                                    cx_cont=false;
                                                                    break;
                                                                };
                                                            }
                                                        }
                                                    }
                                                };
                                                {
                                                    a=b;
                                                    cx_ite=cx_ite.next;
                                                };
                                            }
                                            if(cx_cont){
                                                do{
                                                    var b=lverts.front();
                                                    {
                                                        if(u==a||u==b||v==a||v==b)break;
                                                        var sx:Float;
                                                        var sy:Float;
                                                        {
                                                            sx=u.x-a.x;
                                                            sy=u.y-a.y;
                                                        };
                                                        var vx:Float;
                                                        var vy:Float;
                                                        {
                                                            vx=v.x-u.x;
                                                            vy=v.y-u.y;
                                                        };
                                                        var qx:Float;
                                                        var qy:Float;
                                                        {
                                                            qx=b.x-a.x;
                                                            qy=b.y-a.y;
                                                        };
                                                        var den=(vy*qx-vx*qy);
                                                        if(den*den>ZPP_Const.EPSILON){
                                                            den=1/den;
                                                            var t=(qy*sx-qx*sy)*den;
                                                            if(t>ZPP_Const.EPSILON&&t<1-ZPP_Const.EPSILON){
                                                                var s=(vy*sx-vx*sy)*den;
                                                                if(s>ZPP_Const.EPSILON&&s<1-ZPP_Const.EPSILON){
                                                                    cont=false;
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    };
                                                }
                                                while(false);
                                            }
                                        };
                                    };
                                    {
                                        u=v;
                                        cx_ite=cx_ite.next;
                                    };
                                }
                                if(cx_cont){
                                    do{
                                        var v=lverts.front();
                                        {
                                            if(!cont)break;
                                            {
                                                var cx_cont=true;
                                                var cx_ite=lverts.begin();
                                                var a=cx_ite.elem();
                                                cx_ite=cx_ite.next;
                                                while(cx_ite!=null){
                                                    var b=cx_ite.elem();
                                                    {
                                                        if(u==a||u==b||v==a||v==b){
                                                            {
                                                                a=b;
                                                                cx_ite=cx_ite.next;
                                                            };
                                                            continue;
                                                        };
                                                        var sx:Float;
                                                        var sy:Float;
                                                        {
                                                            sx=u.x-a.x;
                                                            sy=u.y-a.y;
                                                        };
                                                        var vx:Float;
                                                        var vy:Float;
                                                        {
                                                            vx=v.x-u.x;
                                                            vy=v.y-u.y;
                                                        };
                                                        var qx:Float;
                                                        var qy:Float;
                                                        {
                                                            qx=b.x-a.x;
                                                            qy=b.y-a.y;
                                                        };
                                                        var den=(vy*qx-vx*qy);
                                                        if(den*den>ZPP_Const.EPSILON){
                                                            den=1/den;
                                                            var t=(qy*sx-qx*sy)*den;
                                                            if(t>ZPP_Const.EPSILON&&t<1-ZPP_Const.EPSILON){
                                                                var s=(vy*sx-vx*sy)*den;
                                                                if(s>ZPP_Const.EPSILON&&s<1-ZPP_Const.EPSILON){
                                                                    cont=false;
                                                                    {
                                                                        cx_cont=false;
                                                                        break;
                                                                    };
                                                                }
                                                            }
                                                        }
                                                    };
                                                    {
                                                        a=b;
                                                        cx_ite=cx_ite.next;
                                                    };
                                                }
                                                if(cx_cont){
                                                    do{
                                                        var b=lverts.front();
                                                        {
                                                            if(u==a||u==b||v==a||v==b)break;
                                                            var sx:Float;
                                                            var sy:Float;
                                                            {
                                                                sx=u.x-a.x;
                                                                sy=u.y-a.y;
                                                            };
                                                            var vx:Float;
                                                            var vy:Float;
                                                            {
                                                                vx=v.x-u.x;
                                                                vy=v.y-u.y;
                                                            };
                                                            var qx:Float;
                                                            var qy:Float;
                                                            {
                                                                qx=b.x-a.x;
                                                                qy=b.y-a.y;
                                                            };
                                                            var den=(vy*qx-vx*qy);
                                                            if(den*den>ZPP_Const.EPSILON){
                                                                den=1/den;
                                                                var t=(qy*sx-qx*sy)*den;
                                                                if(t>ZPP_Const.EPSILON&&t<1-ZPP_Const.EPSILON){
                                                                    var s=(vy*sx-vx*sy)*den;
                                                                    if(s>ZPP_Const.EPSILON&&s<1-ZPP_Const.EPSILON){
                                                                        cont=false;
                                                                        break;
                                                                    }
                                                                }
                                                            }
                                                        };
                                                    }
                                                    while(false);
                                                }
                                            };
                                        };
                                    }
                                    while(false);
                                }
                            };
                            if(!cont)return validation=ValidationResult.SELF_INTERSECTING;
                            else return validation=ValidationResult.VALID;
                        }
                    }
                }
            }
        }
        else return validation;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function validate_lverts(){
        if(zip_lverts){
            zip_lverts=false;
            if(lverts.size()>2){
                validate_area_inertia();
                if(area<0){
                    reverse_vertices();
                    area=-area;
                }
            }
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function reverse_vertices(){
        lverts.reverse();
        gverts.reverse();
        edges.reverse();
        var ite=edges.iterator_at(edgeCnt-1);
        var elem=edges.pop_unsafe();
        edges.insert(ite,elem);
        reverse_flag=!reverse_flag;
        if(wrap_lverts!=null)wrap_lverts.zpp_inner.reverse_flag=reverse_flag;
        if(wrap_gverts!=null)wrap_gverts.zpp_inner.reverse_flag=reverse_flag;
        if(wrap_edges!=null)wrap_edges.zpp_inner.reverse_flag=reverse_flag;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function validate_laxi(){
        if(zip_laxi){
            zip_laxi=false;
            validate_lverts();
            var ite=edges.begin();
            {
                var cx_ite=lverts.begin();
                var u=cx_ite.elem();
                cx_ite=cx_ite.next;
                while(cx_ite!=null){
                    var v=cx_ite.elem();
                    {
                        var edge=ite.elem();
                        ite=ite.next;
                        var dx:Float;
                        var dy:Float;
                        {
                            dx=u.x-v.x;
                            dy=u.y-v.y;
                        };
                        var l=Math.sqrt((dx*dx+dy*dy));
                        edge.length=l;
                        {
                            var t=(1.0/(l));
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                        ret;
                                        #else Math.isNaN(t);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_muleq(in a: "+"d"+",in s: "+"1.0/(l)"+")");
                                #end
                            };
                            dx*=t;
                            dy*=t;
                        };
                        {
                            var t=dx;
                            dx=-dy;
                            dy=t;
                        };
                        edge.lprojection=(dx*u.x+dy*u.y);
                        {
                            edge.lnormx=dx;
                            edge.lnormy=dy;
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.lnormx);
                                        ret;
                                        #else Math.isNaN(edge.lnormx);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(edge.lnormx)"+") :: "+("vec_set(in n: "+"edge.lnorm"+",in x: "+"dx"+",in y: "+"dy"+")");
                                #end
                            };
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.lnormy);
                                        ret;
                                        #else Math.isNaN(edge.lnormy);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(edge.lnormy)"+") :: "+("vec_set(in n: "+"edge.lnorm"+",in x: "+"dx"+",in y: "+"dy"+")");
                                #end
                            };
                        };
                        if(edge.wrap_lnorm!=null){
                            edge.wrap_lnorm.zpp_inner.x=dx;
                            edge.wrap_lnorm.zpp_inner.y=dy;
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.wrap_lnorm.zpp_inner.x);
                                        ret;
                                        #else Math.isNaN(edge.wrap_lnorm.zpp_inner.x);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(edge.wrap_lnorm.zpp_inner.x)"+") :: "+("vec_set(in n: "+"edge.wrap_lnorm.zpp_inner."+",in x: "+"dx"+",in y: "+"dy"+")");
                                #end
                            };
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.wrap_lnorm.zpp_inner.y);
                                        ret;
                                        #else Math.isNaN(edge.wrap_lnorm.zpp_inner.y);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(edge.wrap_lnorm.zpp_inner.y)"+") :: "+("vec_set(in n: "+"edge.wrap_lnorm.zpp_inner."+",in x: "+"dx"+",in y: "+"dy"+")");
                                #end
                            };
                        };
                    };
                    u=v;
                    cx_ite=cx_ite.next;
                }
                var v=lverts.front();
                {
                    var edge=ite.elem();
                    ite=ite.next;
                    var dx:Float;
                    var dy:Float;
                    {
                        dx=u.x-v.x;
                        dy=u.y-v.y;
                    };
                    var l=Math.sqrt((dx*dx+dy*dy));
                    edge.length=l;
                    {
                        var t=(1.0/(l));
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                    ret;
                                    #else Math.isNaN(t);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_muleq(in a: "+"d"+",in s: "+"1.0/(l)"+")");
                            #end
                        };
                        dx*=t;
                        dy*=t;
                    };
                    {
                        var t=dx;
                        dx=-dy;
                        dy=t;
                    };
                    edge.lprojection=(dx*u.x+dy*u.y);
                    {
                        edge.lnormx=dx;
                        edge.lnormy=dy;
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.lnormx);
                                    ret;
                                    #else Math.isNaN(edge.lnormx);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(edge.lnormx)"+") :: "+("vec_set(in n: "+"edge.lnorm"+",in x: "+"dx"+",in y: "+"dy"+")");
                            #end
                        };
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.lnormy);
                                    ret;
                                    #else Math.isNaN(edge.lnormy);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(edge.lnormy)"+") :: "+("vec_set(in n: "+"edge.lnorm"+",in x: "+"dx"+",in y: "+"dy"+")");
                            #end
                        };
                    };
                    if(edge.wrap_lnorm!=null){
                        edge.wrap_lnorm.zpp_inner.x=dx;
                        edge.wrap_lnorm.zpp_inner.y=dy;
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.wrap_lnorm.zpp_inner.x);
                                    ret;
                                    #else Math.isNaN(edge.wrap_lnorm.zpp_inner.x);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(edge.wrap_lnorm.zpp_inner.x)"+") :: "+("vec_set(in n: "+"edge.wrap_lnorm.zpp_inner."+",in x: "+"dx"+",in y: "+"dy"+")");
                            #end
                        };
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](edge.wrap_lnorm.zpp_inner.y);
                                    ret;
                                    #else Math.isNaN(edge.wrap_lnorm.zpp_inner.y);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(edge.wrap_lnorm.zpp_inner.y)"+") :: "+("vec_set(in n: "+"edge.wrap_lnorm.zpp_inner."+",in x: "+"dx"+",in y: "+"dy"+")");
                            #end
                        };
                    };
                };
            };
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function validate_gverts(){
        if(zip_gverts){
            if(body!=null){
                zip_gverts=false;
                validate_lverts();
                body.validate_axis();
                var li=lverts.begin();
                {
                    var cx_ite=gverts.begin();
                    while(cx_ite!=null){
                        var g=cx_ite.elem();
                        {
                            var l=li.elem();
                            li=li.next;
                            {
                                g.x=body.posx+(body.axisy*l.x-body.axisx*l.y);
                                g.y=body.posy+(l.x*body.axisx+l.y*body.axisy);
                            };
                        };
                        cx_ite=cx_ite.next;
                    }
                };
            }
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function validate_gaxi(){
        if(zip_gaxi){
            if(body!=null){
                zip_gaxi=false;
                validate_laxi();
                body.validate_axis();
                {
                    var cx_ite=edges.begin();
                    while(cx_ite!=null){
                        var e=cx_ite.elem();
                        {
                            {
                                e.gnormx=(body.axisy*e.lnormx-body.axisx*e.lnormy);
                                e.gnormy=(e.lnormx*body.axisx+e.lnormy*body.axisy);
                            };
                            e.gprojection=(body.posx*e.gnormx+body.posy*e.gnormy)+e.lprojection;
                            if(e.wrap_gnorm!=null){
                                e.wrap_gnorm.zpp_inner.x=e.gnormx;
                                e.wrap_gnorm.zpp_inner.y=e.gnormy;
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](e.wrap_gnorm.zpp_inner.x);
                                            ret;
                                            #else Math.isNaN(e.wrap_gnorm.zpp_inner.x);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(e.wrap_gnorm.zpp_inner.x)"+") :: "+("vec_set(in n: "+"e.wrap_gnorm.zpp_inner."+",in x: "+"e.gnormx"+",in y: "+"e.gnormy"+")");
                                    #end
                                };
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](e.wrap_gnorm.zpp_inner.y);
                                            ret;
                                            #else Math.isNaN(e.wrap_gnorm.zpp_inner.y);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(e.wrap_gnorm.zpp_inner.y)"+") :: "+("vec_set(in n: "+"e.wrap_gnorm.zpp_inner."+",in x: "+"e.gnormx"+",in y: "+"e.gnormy"+")");
                                    #end
                                };
                            };
                        };
                        cx_ite=cx_ite.next;
                    }
                };
            }
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __validate_aabb(){
        if(lverts.empty())throw "Error: An empty polygon has no meaningful bounds";
        validate_gverts();
        var p0=gverts.front();
        {
            aabb.minx=p0.x;
            aabb.miny=p0.y;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](aabb.minx);
                        ret;
                        #else Math.isNaN(aabb.minx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(aabb.minx)"+") :: "+("vec_set(in n: "+"aabb.min"+",in x: "+"p0.x"+",in y: "+"p0.y"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](aabb.miny);
                        ret;
                        #else Math.isNaN(aabb.miny);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(aabb.miny)"+") :: "+("vec_set(in n: "+"aabb.min"+",in x: "+"p0.x"+",in y: "+"p0.y"+")");
                #end
            };
        };
        {
            aabb.maxx=p0.x;
            aabb.maxy=p0.y;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](aabb.maxx);
                        ret;
                        #else Math.isNaN(aabb.maxx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(aabb.maxx)"+") :: "+("vec_set(in n: "+"aabb.max"+",in x: "+"p0.x"+",in y: "+"p0.y"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](aabb.maxy);
                        ret;
                        #else Math.isNaN(aabb.maxy);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(aabb.maxy)"+") :: "+("vec_set(in n: "+"aabb.max"+",in x: "+"p0.x"+",in y: "+"p0.y"+")");
                #end
            };
        };
        {
            var cx_ite=gverts.begin().next;
            while(cx_ite!=null){
                var p=cx_ite.elem();
                {
                    if(p.x<aabb.minx)aabb.minx=p.x;
                    if(p.x>aabb.maxx)aabb.maxx=p.x;
                    if(p.y<aabb.miny)aabb.miny=p.y;
                    if(p.y>aabb.maxy)aabb.maxy=p.y;
                };
                cx_ite=cx_ite.next;
            }
        };
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __validate_area_inertia(){
        if(lverts.begin()==null||lverts.begin().next==null||lverts.begin().next.next==null){
            area=0;
            inertia=0;
        }
        else{
            area=0.;
            var s1=0.;
            var s2=0.;
            {
                var cx_ite=lverts.begin();
                var u=cx_ite.elem();
                cx_ite=cx_ite.next;
                var v=cx_ite.elem();
                cx_ite=cx_ite.next;
                while(cx_ite!=null){
                    var w=cx_ite.elem();
                    {
                        var a=(v.y*u.x-v.x*u.y);
                        var b=(v.x*v.x+v.y*v.y)+(v.x*u.x+v.y*u.y)+(u.x*u.x+u.y*u.y);
                        s1+=a*b;
                        s2+=a;
                        area+=v.x*(w.y-u.y);
                    };
                    u=v;
                    v=w;
                    cx_ite=cx_ite.next;
                }
                cx_ite=lverts.begin();
                var w=cx_ite.elem();
                {
                    var a=(v.y*u.x-v.x*u.y);
                    var b=(v.x*v.x+v.y*v.y)+(v.x*u.x+v.y*u.y)+(u.x*u.x+u.y*u.y);
                    s1+=a*b;
                    s2+=a;
                    area+=v.x*(w.y-u.y);
                };
                u=v;
                v=w;
                cx_ite=cx_ite.next;
                var w=cx_ite.elem();
                {
                    var a=(v.y*u.x-v.x*u.y);
                    var b=(v.x*v.x+v.y*v.y)+(v.x*u.x+v.y*u.y)+(u.x*u.x+u.y*u.y);
                    s1+=a*b;
                    s2+=a;
                    area+=v.x*(w.y-u.y);
                };
            };
            inertia=s1/(6*s2);
            area*=0.5;
            if(area<0){
                area=-area;
                reverse_vertices();
            }
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __validate_angDrag(){
        if(lverts.size()<3)throw "Error: Polygon's with less than 3 vertices have no meaningful angDrag";
        validate_area_inertia();
        validate_laxi();
        var accum=0.;
        var ei=edges.begin();
        var perim=0.;
        {
            var cx_cont=true;
            var cx_itei=lverts.begin();
            var u=cx_itei.elem();
            var cx_itej=cx_itei.next;
            while(cx_itej!=null){
                var v=cx_itej.elem();
                {
                    var edge=ei.elem();
                    ei=ei.next;
                    perim+=edge.length;
                    var dx:Float;
                    var dy:Float;
                    {
                        dx=v.x-u.x;
                        dy=v.y-u.y;
                    };
                    accum+=edge.length*ZPP_Config.ANGDRAGCOEF_FRICTION*material.dynamicFriction*edge.lprojection*edge.lprojection;
                    var t=-(u.y*edge.lnormx-u.x*edge.lnormy)/(dy*edge.lnormx-dx*edge.lnormy);
                    if(t>0){
                        var ta=if(t>1)1 else t;
                        var cx:Float;
                        var cy:Float;
                        {
                            cx=u.x;
                            cy=u.y;
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](cx);
                                        ret;
                                        #else Math.isNaN(cx);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(cx)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                #end
                            };
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](cy);
                                        ret;
                                        #else Math.isNaN(cy);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(cy)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                #end
                            };
                        };
                        {
                            var t=(ta);
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                        ret;
                                        #else Math.isNaN(t);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"c"+",in b: "+"d"+",in s: "+"ta"+")");
                                #end
                            };
                            cx+=dx*t;
                            cy+=dy*t;
                        };
                        var dota=(edge.lnormy*u.x-edge.lnormx*u.y);
                        var dotb=(edge.lnormy*cx-edge.lnormx*cy);
                        var dots=(dotb*dotb*dotb-dota*dota*dota)/(3*(dotb-dota));
                        accum+=dots*ta*edge.length*ZPP_Config.ANGDRAGCOEF_DRAG;
                    }
                    if(t<1){
                        var tb=if(t<0)0 else t;
                        var cx:Float;
                        var cy:Float;
                        {
                            cx=u.x;
                            cy=u.y;
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](cx);
                                        ret;
                                        #else Math.isNaN(cx);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(cx)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                #end
                            };
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](cy);
                                        ret;
                                        #else Math.isNaN(cy);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(cy)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                #end
                            };
                        };
                        {
                            var t=(tb);
                            {
                                #if NAPE_ASSERT var res={
                                    !({
                                        #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                        ret;
                                        #else Math.isNaN(t);
                                        #end
                                    });
                                };
                                if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"c"+",in b: "+"d"+",in s: "+"tb"+")");
                                #end
                            };
                            cx+=dx*t;
                            cy+=dy*t;
                        };
                        var dota=(edge.lnormy*cx-edge.lnormx*cy);
                        var dotb=(edge.lnormy*v.x-edge.lnormx*v.y);
                        var dots=(dotb*dotb*dotb-dota*dota*dota)/(3*(dotb-dota));
                        accum+=dots*ZPP_Config.ANGDRAGCOEF_VACUUM*(1-tb)*edge.length*ZPP_Config.ANGDRAGCOEF_DRAG;
                    }
                };
                {
                    cx_itei=cx_itej;
                    u=v;
                    cx_itej=cx_itej.next;
                };
            }
            if(cx_cont){
                do{
                    cx_itej=lverts.begin();
                    var v=cx_itej.elem();
                    {
                        var edge=ei.elem();
                        ei=ei.next;
                        perim+=edge.length;
                        var dx:Float;
                        var dy:Float;
                        {
                            dx=v.x-u.x;
                            dy=v.y-u.y;
                        };
                        accum+=edge.length*ZPP_Config.ANGDRAGCOEF_FRICTION*material.dynamicFriction*edge.lprojection*edge.lprojection;
                        var t=-(u.y*edge.lnormx-u.x*edge.lnormy)/(dy*edge.lnormx-dx*edge.lnormy);
                        if(t>0){
                            var ta=if(t>1)1 else t;
                            var cx:Float;
                            var cy:Float;
                            {
                                cx=u.x;
                                cy=u.y;
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](cx);
                                            ret;
                                            #else Math.isNaN(cx);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(cx)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                    #end
                                };
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](cy);
                                            ret;
                                            #else Math.isNaN(cy);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(cy)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                    #end
                                };
                            };
                            {
                                var t=(ta);
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                            ret;
                                            #else Math.isNaN(t);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"c"+",in b: "+"d"+",in s: "+"ta"+")");
                                    #end
                                };
                                cx+=dx*t;
                                cy+=dy*t;
                            };
                            var dota=(edge.lnormy*u.x-edge.lnormx*u.y);
                            var dotb=(edge.lnormy*cx-edge.lnormx*cy);
                            var dots=(dotb*dotb*dotb-dota*dota*dota)/(3*(dotb-dota));
                            accum+=dots*ta*edge.length*ZPP_Config.ANGDRAGCOEF_DRAG;
                        }
                        if(t<1){
                            var tb=if(t<0)0 else t;
                            var cx:Float;
                            var cy:Float;
                            {
                                cx=u.x;
                                cy=u.y;
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](cx);
                                            ret;
                                            #else Math.isNaN(cx);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(cx)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                    #end
                                };
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](cy);
                                            ret;
                                            #else Math.isNaN(cy);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(cy)"+") :: "+("vec_set(in n: "+"c"+",in x: "+"u.x"+",in y: "+"u.y"+")");
                                    #end
                                };
                            };
                            {
                                var t=(tb);
                                {
                                    #if NAPE_ASSERT var res={
                                        !({
                                            #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                            ret;
                                            #else Math.isNaN(t);
                                            #end
                                        });
                                    };
                                    if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"c"+",in b: "+"d"+",in s: "+"tb"+")");
                                    #end
                                };
                                cx+=dx*t;
                                cy+=dy*t;
                            };
                            var dota=(edge.lnormy*cx-edge.lnormx*cy);
                            var dotb=(edge.lnormy*v.x-edge.lnormx*v.y);
                            var dots=(dotb*dotb*dotb-dota*dota*dota)/(3*(dotb-dota));
                            accum+=dots*ZPP_Config.ANGDRAGCOEF_VACUUM*(1-tb)*edge.length*ZPP_Config.ANGDRAGCOEF_DRAG;
                        }
                    };
                }
                while(false);
            }
        };
        angDrag=accum/(inertia*perim);
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __validate_localCOM(){
        if(lverts.empty())throw "Error: An empty polygon has no meaningful localCOM";
        if(lverts.begin().next==null){
            localCOMx=lverts.front().x;
            localCOMy=lverts.front().y;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMx);
                        ret;
                        #else Math.isNaN(localCOMx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(localCOMx)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"lverts.front().x"+",in y: "+"lverts.front().y"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMy);
                        ret;
                        #else Math.isNaN(localCOMy);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(localCOMy)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"lverts.front().x"+",in y: "+"lverts.front().y"+")");
                #end
            };
        };
        else if(lverts.begin().next.next==null){
            {
                localCOMx=lverts.front().x;
                localCOMy=lverts.front().y;
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMx);
                            ret;
                            #else Math.isNaN(localCOMx);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(localCOMx)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"lverts.front().x"+",in y: "+"lverts.front().y"+")");
                    #end
                };
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMy);
                            ret;
                            #else Math.isNaN(localCOMy);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(localCOMy)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"lverts.front().x"+",in y: "+"lverts.front().y"+")");
                    #end
                };
            };
            {
                var t=(1.0);
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                            ret;
                            #else Math.isNaN(t);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"localCOM"+",in b: "+"lverts.begin().next.elem()."+",in s: "+"1.0"+")");
                    #end
                };
                localCOMx+=lverts.begin().next.elem().x*t;
                localCOMy+=lverts.begin().next.elem().y*t;
            };
            {
                var t=(0.5);
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                            ret;
                            #else Math.isNaN(t);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_muleq(in a: "+"localCOM"+",in s: "+"0.5"+")");
                    #end
                };
                localCOMx*=t;
                localCOMy*=t;
            };
        }
        else{
            {
                localCOMx=0;
                localCOMy=0;
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMx);
                            ret;
                            #else Math.isNaN(localCOMx);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(localCOMx)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"0"+",in y: "+"0"+")");
                    #end
                };
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](localCOMy);
                            ret;
                            #else Math.isNaN(localCOMy);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(localCOMy)"+") :: "+("vec_set(in n: "+"localCOM"+",in x: "+"0"+",in y: "+"0"+")");
                    #end
                };
            };
            var area=0.0;
            {
                var cx_ite=lverts.begin();
                var u=cx_ite.elem();
                cx_ite=cx_ite.next;
                var v=cx_ite.elem();
                cx_ite=cx_ite.next;
                while(cx_ite!=null){
                    var w=cx_ite.elem();
                    {
                        area+=v.x*(w.y-u.y);
                        var cf=(w.y*v.x-w.x*v.y);
                        localCOMx+=(v.x+w.x)*cf;
                        localCOMy+=(v.y+w.y)*cf;
                    };
                    u=v;
                    v=w;
                    cx_ite=cx_ite.next;
                }
                cx_ite=lverts.begin();
                var w=cx_ite.elem();
                {
                    area+=v.x*(w.y-u.y);
                    var cf=(w.y*v.x-w.x*v.y);
                    localCOMx+=(v.x+w.x)*cf;
                    localCOMy+=(v.y+w.y)*cf;
                };
                u=v;
                v=w;
                cx_ite=cx_ite.next;
                var w=cx_ite.elem();
                {
                    area+=v.x*(w.y-u.y);
                    var cf=(w.y*v.x-w.x*v.y);
                    localCOMx+=(v.x+w.x)*cf;
                    localCOMy+=(v.y+w.y)*cf;
                };
            };
            area=1/(3*area);
            {
                var t=(area);
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                            ret;
                            #else Math.isNaN(t);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_muleq(in a: "+"localCOM"+",in s: "+"area"+")");
                    #end
                };
                localCOMx*=t;
                localCOMy*=t;
            };
        }
    }
    public function setupLocalCOM(){
        var me=this;
        wrap_localCOM=new Vec2();
        wrap_localCOM.zpp_inner.inuse=true;
        wrap_localCOM.zpp_inner._validate=function(){
            if(me.lverts.empty())throw "Error: An empty polygon does not have any meaningful localCOM";
            me.validate_localCOM();
        };
        wrap_localCOM.zpp_inner._invalidate=function(x:ZPP_Vec2){
            throw "not done yet";
        };
    }
    public function new(){
        super(ZPP_Flags.id_ShapeType_POLYGON);
        polygon=this;
        lverts=new ZPP_Vec2();
        gverts=new ZPP_Vec2();
        edges=new ZNPList_ZPP_Edge();
        edgeCnt=0;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __translate(dx:Float,dy:Float){
        {
            var cx_ite=lverts.begin();
            while(cx_ite!=null){
                var p=cx_ite.elem();
                {
                    var t=(1.0);
                    {
                        #if NAPE_ASSERT var res={
                            !({
                                #if flash9 var ret:Bool=untyped __global__["isNaN"](t);
                                ret;
                                #else Math.isNaN(t);
                                #end
                            });
                        };
                        if(!res)throw "assert("+"!assert_isNaN(t)"+") :: "+("vec_addeq(in a: "+"p."+",in b: "+"d"+",in s: "+"1.0"+")");
                        #end
                    };
                    p.x+=dx*t;
                    p.y+=dy*t;
                };
                cx_ite=cx_ite.next;
            }
        };
        invalidate_lverts();
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __scale(sx:Float,sy:Float){
        {
            var cx_ite=lverts.begin();
            while(cx_ite!=null){
                var p=cx_ite.elem();
                {
                    p.x*=sx;
                    p.y*=sy;
                };
                cx_ite=cx_ite.next;
            }
        };
        invalidate_lverts();
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __rotate(ax:Float,ay:Float){
        {
            var cx_ite=lverts.begin();
            while(cx_ite!=null){
                var p=cx_ite.elem();
                {
                    var tempx:Float;
                    var tempy:Float;
                    {
                        tempx=(ay*p.x-ax*p.y);
                        tempy=(p.x*ax+p.y*ay);
                    };
                    {
                        p.x=tempx;
                        p.y=tempy;
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](p.x);
                                    ret;
                                    #else Math.isNaN(p.x);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(p.x)"+") :: "+("vec_set(in n: "+"p."+",in x: "+"tempx"+",in y: "+"tempy"+")");
                            #end
                        };
                        {
                            #if NAPE_ASSERT var res={
                                !({
                                    #if flash9 var ret:Bool=untyped __global__["isNaN"](p.y);
                                    ret;
                                    #else Math.isNaN(p.y);
                                    #end
                                });
                            };
                            if(!res)throw "assert("+"!assert_isNaN(p.y)"+") :: "+("vec_set(in n: "+"p."+",in x: "+"tempx"+",in y: "+"tempy"+")");
                            #end
                        };
                    };
                };
                cx_ite=cx_ite.next;
            }
        };
        invalidate_lverts();
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __transform(mat:Mat23){
        {
            var cx_ite=lverts.begin();
            while(cx_ite!=null){
                var p=cx_ite.elem();
                {
                    {
                        var t=mat.a*p.x+mat.b*p.y;
                        p.y=mat.c*p.x+mat.d*p.y;
                        p.x=t;
                    };
                };
                cx_ite=cx_ite.next;
            }
        };
        invalidate_lverts();
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function __copy(){
        var ret=new Polygon(outer_zn.localVerts).zpp_inner_zn;
        return ret;
    }
}
